package co.edu.usbcali.sisgpim.presentation.backEndBeans;

import co.edu.usbcali.sisgpim.exceptions.*;
import co.edu.usbcali.sisgpim.modelo.*;
import co.edu.usbcali.sisgpim.modelo.dto.UsuariosDTO;
import co.edu.usbcali.sisgpim.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.sisgpim.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlSelectBooleanCheckbox;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.ext.HtmlSelectOneRadio;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;


/**
*
*
* @author Zathura Code Generator http://code.google.com/p/zathura/
*
*/
public class UsuariosView extends DataSource implements Renderable,
    DisposableBean {
    private HtmlInputText txtApellidos;
    //private HtmlInputText txtBloqueado;
    private HtmlSelectOneRadio sorBloqueado;
    private SelectItem[] siBloqueado;
    private HtmlInputText txtCorreoElectronico;
    private HtmlInputText txtNombres;
    private HtmlInputText txtTelefono;
    //private HtmlInputText txtCodigo_TiposUsuario;
    private HtmlSelectOneMenu somTiposUsuarios;
    private SelectItem[] siTiposUsuarios;
    private HtmlInputText txtCodigo;
    private SelectInputDate txtFechaDesbloqueo;
    private SelectInputDate txtFechaNacimiento;
    private HtmlCommandButton btnSave;
    private HtmlCommandButton btnModify;
    private HtmlCommandButton btnDelete;
    private HtmlCommandButton btnClear;
    private boolean renderDataTable;
    private boolean flag = true;
    private RenderManager renderManager;
    private PersistentFacesState state = PersistentFacesState.getInstance();
    private List<Usuarios> usuarios;
    private List<UsuariosDTO> usuariosDTO;

    public UsuariosView() {
        super("");
        loadTipoUsuarios();
        loadSorBloqueados();
    }
    
    public void loadSorBloqueados(){
    	siBloqueado = new SelectItem[2];
		siBloqueado[0] = new SelectItem(Boolean.FALSE, "No");
		siBloqueado[1] = new SelectItem(Boolean.TRUE, "Si");
    }
    
    public void loadTipoUsuarios(){
    	try {
    		List<TiposUsuario> tiposUsuarios = BusinessDelegatorView.getTiposUsuario();
			if(tiposUsuarios != null && tiposUsuarios.size() > 0){
				somTiposUsuarios = new HtmlSelectOneMenu();
				int i = tiposUsuarios.size();
				siTiposUsuarios = new SelectItem[i];
				
				for (int j = 0; j < i; j++) {
					TiposUsuario usuario = tiposUsuarios.get(j);
					siTiposUsuarios[j] = new SelectItem(usuario.getCodigo(),usuario.getNombre());
				}
			}
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}
    }

    public String action_clear() {
        txtApellidos.setValue(null);
        txtApellidos.setDisabled(true);
        //txtBloqueado.setValue(null);
        //txtBloqueado.setDisabled(true);
        txtCorreoElectronico.setValue(null);
        txtCorreoElectronico.setDisabled(true);
        txtNombres.setValue(null);
        txtNombres.setDisabled(true);
        txtTelefono.setValue(null);
        txtTelefono.setDisabled(true);
        /*txtCodigo_TiposUsuario.setValue(null);
        txtCodigo_TiposUsuario.setDisabled(true);*/
        somTiposUsuarios.setValue(null);
        somTiposUsuarios.setDisabled(true);
        txtFechaDesbloqueo.setValue(null);
        txtFechaDesbloqueo.setDisabled(true);
        txtFechaNacimiento.setValue(null);
        txtFechaNacimiento.setDisabled(true);
        txtCodigo.setValue(null);
        txtCodigo.setDisabled(false);
        btnSave.setDisabled(true);
        btnDelete.setDisabled(true);
        btnModify.setDisabled(true);
        btnClear.setDisabled(false);

        return "";
    }

    public void listener_txtId(ValueChangeEvent event) {
        if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
            Usuarios entity = null;

            try {
                Integer codigo = new Integer(txtCodigo.getValue().toString());
                entity = BusinessDelegatorView.getUsuarios(codigo);
            } catch (Exception e) {
                // TODO: handle exception
            }

            if (entity == null) {
                txtApellidos.setDisabled(false);
                //txtBloqueado.setDisabled(false);
                sorBloqueado.setDisabled(false);
                sorBloqueado.setValue(Boolean.FALSE);
                txtCorreoElectronico.setDisabled(false);
                txtNombres.setDisabled(false);
                txtTelefono.setDisabled(false);
                //txtCodigo_TiposUsuario.setDisabled(false);
                somTiposUsuarios.setDisabled(false);
                //txtFechaDesbloqueo.setDisabled(false);
                txtFechaNacimiento.setDisabled(false);
                txtCodigo.setDisabled(false);
                btnSave.setDisabled(false);
                btnDelete.setDisabled(true);
                btnModify.setDisabled(true);
                btnClear.setDisabled(false);
            } else {
                txtApellidos.setValue(entity.getApellidos());
                txtApellidos.setDisabled(false);
                /*txtBloqueado.setValue(entity.isBloqueado());
                txtBloqueado.setDisabled(false);*/
                sorBloqueado.setValue(entity.isBloqueado());
                sorBloqueado.setDisabled(false);
                txtCorreoElectronico.setValue(entity.getCorreoElectronico());
                txtCorreoElectronico.setDisabled(false);
                txtFechaDesbloqueo.setValue(entity.getFechaDesbloqueo());
                //txtFechaDesbloqueo.setDisabled(false);
                txtFechaNacimiento.setValue(entity.getFechaNacimiento());
                txtFechaNacimiento.setDisabled(false);
                txtNombres.setValue(entity.getNombres());
                txtNombres.setDisabled(false);
                txtTelefono.setValue(entity.getTelefono());
                txtTelefono.setDisabled(false);
                //txtCodigo_TiposUsuario.setValue(entity.getTiposUsuario().getCodigo());
                //txtCodigo_TiposUsuario.setDisabled(false);
                somTiposUsuarios.setValue(entity.getTiposUsuario().getCodigo());
                somTiposUsuarios.setDisabled(false);
                txtCodigo.setValue(entity.getCodigo());
                txtCodigo.setDisabled(true);
                btnSave.setDisabled(true);
                btnDelete.setDisabled(false);
                btnModify.setDisabled(false);
                btnClear.setDisabled(false);
            }
        }
    }
    
   

    public String action_save() {
        try {
        	Integer tipoUsuarioCod = Integer.parseInt(somTiposUsuarios.getValue().toString());
            BusinessDelegatorView.saveUsuarios(
            	FacesUtils.checkString(txtApellidos), 
            	new Boolean(sorBloqueado.getValue().toString()),
                FacesUtils.checkInteger(txtCodigo),
                FacesUtils.checkString(txtCorreoElectronico),
                FacesUtils.checkDate(txtFechaDesbloqueo),
                FacesUtils.checkDate(txtFechaNacimiento),
                FacesUtils.checkString(txtNombres),
                FacesUtils.checkString(txtTelefono),
                FacesUtils.checkInteger(somTiposUsuarios));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_delete() {
        try {
            BusinessDelegatorView.deleteUsuarios(FacesUtils.checkInteger(
                    txtCodigo));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modify() {
        try {
            BusinessDelegatorView.updateUsuarios(
            	FacesUtils.checkString(txtApellidos), 
            	new Boolean(sorBloqueado.getValue().toString()),
                FacesUtils.checkInteger(txtCodigo),
                FacesUtils.checkString(txtCorreoElectronico),
                FacesUtils.checkDate(txtFechaDesbloqueo),
                FacesUtils.checkDate(txtFechaNacimiento),
                FacesUtils.checkString(txtNombres),
                FacesUtils.checkString(txtTelefono),
                FacesUtils.checkInteger(Integer.parseInt(somTiposUsuarios.getValue().toString())));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modifyWitDTO(String apellidos, boolean bloqueado,
        Integer codigo, String correoElectronico, Date fechaDesbloqueo,
        Date fechaNacimiento, String nombres, String telefono,
        Integer codigo_TiposUsuario) throws Exception {
        try {
            BusinessDelegatorView.updateUsuarios(apellidos, bloqueado, codigo,
                correoElectronico, fechaDesbloqueo, fechaNacimiento, nombres,
                telefono, codigo_TiposUsuario);
            renderManager.getOnDemandRenderer("UsuariosView").requestRender();
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
        } catch (Exception e) {
            //renderManager.getOnDemandRenderer("UsuariosView").requestRender();
            FacesUtils.addErrorMessage(e.getMessage());
            throw e;
        }

        return "";
    }

    public List<Usuarios> getUsuarios() {
        if (flag) {
            try {
                usuarios = BusinessDelegatorView.getUsuarios();
                flag = false;
            } catch (Exception e) {
                flag = true;
                FacesUtils.addErrorMessage(e.getMessage());
            }
        }

        return usuarios;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setUsuarios(List<Usuarios> usuarios) {
        this.usuarios = usuarios;
    }

    public boolean isRenderDataTable() {
        try {
            if (flag) {
                if (BusinessDelegatorView.findTotalNumberUsuarios() > 0) {
                    renderDataTable = true;
                } else {
                    renderDataTable = false;
                }
            }

            flag = false;
        } catch (Exception e) {
            renderDataTable = false;
            e.printStackTrace();
        }

        return renderDataTable;
    }

    public DataModel getData() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModel(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<Usuarios> getDataPage(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberUsuarios = 0;

        try {
            totalNumberUsuarios = BusinessDelegatorView.findTotalNumberUsuarios()
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberUsuarios) {
            endIndex = totalNumberUsuarios;
        }

        try {
            usuarios = BusinessDelegatorView.findPageUsuarios(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            // Remove this Renderable from the existing render groups.
            //leaveRenderGroups();        			
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        //joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<Usuarios>(totalNumberUsuarios, startRow, usuarios);
    }

    public DataModel getDataDTO() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModelDTO(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<UsuariosDTO> getDataPageDTO(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberUsuarios = 0;

        try {
            totalNumberUsuarios = BusinessDelegatorView.findTotalNumberUsuarios()
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberUsuarios) {
            endIndex = totalNumberUsuarios;
        }

        try {
            usuarios = BusinessDelegatorView.findPageUsuarios(sortColumnName,
                    sortAscending, startRow, endIndex - startRow);

            if (Utilities.validationsList(usuarios)) {
                usuariosDTO = new ArrayList<UsuariosDTO>();

                for (Usuarios usuariosTmp : usuarios) {
                    UsuariosDTO usuariosDTO2 = new UsuariosDTO();
                    usuariosDTO2.setCodigo(usuariosTmp.getCodigo().toString());
                    usuariosDTO2.setApellidos((usuariosTmp.getApellidos() != null)
                        ? usuariosTmp.getApellidos().toString() : null);
                    usuariosDTO2.setBloqueado((usuariosTmp.isBloqueado() != null)
                        ? usuariosTmp.isBloqueado().toString() : null);
                    usuariosDTO2.setCorreoElectronico((usuariosTmp.getCorreoElectronico() != null)
                        ? usuariosTmp.getCorreoElectronico().toString() : null);
                    usuariosDTO2.setFechaDesbloqueo(usuariosTmp.getFechaDesbloqueo());
                    usuariosDTO2.setFechaNacimiento(usuariosTmp.getFechaNacimiento());
                    usuariosDTO2.setNombres((usuariosTmp.getNombres() != null)
                        ? usuariosTmp.getNombres().toString() : null);
                    usuariosDTO2.setTelefono((usuariosTmp.getTelefono() != null)
                        ? usuariosTmp.getTelefono().toString() : null);
                    usuariosDTO2.setCodigo_TiposUsuario((usuariosTmp.getTiposUsuario()
                                                                    .getCodigo() != null)
                        ? usuariosTmp.getTiposUsuario().getCodigo().toString()
                        : null);
                    usuariosDTO2.setUsuarios(usuariosTmp);
                    usuariosDTO2.setUsuariosView(this);
                    usuariosDTO.add(usuariosDTO2);
                }
            }

            // Remove this Renderable from the existing render groups.
            leaveRenderGroups();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<UsuariosDTO>(totalNumberUsuarios, startRow,
            usuariosDTO);
    }

    protected boolean isDefaultAscending(String sortColumn) {
        return true;
    }

    /**
    * This method is called when a render call is made from the server. Render
    * calls are only made to views containing an updated record. The data is
    * marked as dirty to trigger a fetch of the updated record from the
    * database before rendering takes place.
    */
    public PersistentFacesState getState() {
        onePageDataModel.setDirtyData();

        return state;
    }

    /**
    * This method is called from faces-config.xml with each new session.
    */
    public void setRenderManager(RenderManager renderManager) {
        this.renderManager = renderManager;
    }

    public void renderingException(RenderingException arg0) {
        if (arg0 instanceof TransientRenderingException) {
        } else if (arg0 instanceof FatalRenderingException) {
            // Remove from existing Customer render groups.
            leaveRenderGroups();
        }
    }

    /**
    * Remove this Renderable from existing uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void leaveRenderGroups() {
        if (Utilities.validationsList(usuariosDTO)) {
            for (UsuariosDTO usuariosTmp : usuariosDTO) {
                renderManager.getOnDemandRenderer("UsuariosView").remove(this);
            }
        }
    }

    /**
    * Add this Renderable to the new uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void joinRenderGroups() {
        if (Utilities.validationsList(usuariosDTO)) {
            for (UsuariosDTO usuariosTmp : usuariosDTO) {
                renderManager.getOnDemandRenderer("UsuariosView").add(this);
            }
        }
    }

    public void dispose() throws Exception {
    }

    public RenderManager getRenderManager() {
        return renderManager;
    }

    public void setState(PersistentFacesState state) {
        this.state = state;
    }

    public HtmlInputText getTxtApellidos() {
        return txtApellidos;
    }

    public void setTxtApellidos(HtmlInputText txtApellidos) {
        this.txtApellidos = txtApellidos;
    }

    public HtmlSelectOneRadio getSorBloqueado() {
		return sorBloqueado;
	}

	public void setSorBloqueado(HtmlSelectOneRadio sorBloqueado) {
		this.sorBloqueado = sorBloqueado;
	}

	public SelectItem[] getSiBloqueado() {		
		return siBloqueado;
	}

	/*public HtmlInputText getTxtBloqueado() {
        return txtBloqueado;
    }

    public void setTxtBloqueado(HtmlInputText txtBloqueado) {
        this.txtBloqueado = txtBloqueado;
    }*/

    public HtmlInputText getTxtCorreoElectronico() {
        return txtCorreoElectronico;
    }

    public void setTxtCorreoElectronico(HtmlInputText txtCorreoElectronico) {
        this.txtCorreoElectronico = txtCorreoElectronico;
    }

    public HtmlInputText getTxtNombres() {
        return txtNombres;
    }

    public void setTxtNombres(HtmlInputText txtNombres) {
        this.txtNombres = txtNombres;
    }

    public HtmlInputText getTxtTelefono() {
        return txtTelefono;
    }

    public void setTxtTelefono(HtmlInputText txtTelefono) {
        this.txtTelefono = txtTelefono;
    }

    /*public HtmlInputText getTxtCodigo_TiposUsuario() {
        return txtCodigo_TiposUsuario;
    }

    public void setTxtCodigo_TiposUsuario(HtmlInputText txtCodigo_TiposUsuario) {
        this.txtCodigo_TiposUsuario = txtCodigo_TiposUsuario;
    }*/
    
    public HtmlSelectOneMenu getSomTiposUsuarios() {
		return somTiposUsuarios;
	}

	public void setSomTiposUsuarios(HtmlSelectOneMenu somTiposUsuarios) {
		this.somTiposUsuarios = somTiposUsuarios;
	}

	public SelectItem[] getSiTiposUsuarios() {
		return siTiposUsuarios;
	}

	public SelectInputDate getTxtFechaDesbloqueo() {
        return txtFechaDesbloqueo;
    }

    public void setTxtFechaDesbloqueo(SelectInputDate txtFechaDesbloqueo) {
        this.txtFechaDesbloqueo = txtFechaDesbloqueo;
    }

    public SelectInputDate getTxtFechaNacimiento() {
        return txtFechaNacimiento;
    }

    public void setTxtFechaNacimiento(SelectInputDate txtFechaNacimiento) {
        this.txtFechaNacimiento = txtFechaNacimiento;
    }

    public HtmlInputText getTxtCodigo() {
        return txtCodigo;
    }

    public void setTxtCodigo(HtmlInputText txtCodigo) {
        this.txtCodigo = txtCodigo;
    }

    public HtmlCommandButton getBtnSave() {
        return btnSave;
    }

    public void setBtnSave(HtmlCommandButton btnSave) {
        this.btnSave = btnSave;
    }

    public HtmlCommandButton getBtnModify() {
        return btnModify;
    }

    public void setBtnModify(HtmlCommandButton btnModify) {
        this.btnModify = btnModify;
    }

    public HtmlCommandButton getBtnDelete() {
        return btnDelete;
    }

    public void setBtnDelete(HtmlCommandButton btnDelete) {
        this.btnDelete = btnDelete;
    }

    public HtmlCommandButton getBtnClear() {
        return btnClear;
    }

    public void setBtnClear(HtmlCommandButton btnClear) {
        this.btnClear = btnClear;
    }

    public void setRenderDataTable(boolean renderDataTable) {
        this.renderDataTable = renderDataTable;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<UsuariosDTO> getUsuariosDTO() {
        return usuariosDTO;
    }

    public void setUsuariosDTO(List<UsuariosDTO> usuariosDTO) {
        this.usuariosDTO = usuariosDTO;
    }

    public TimeZone getTimeZone() {
        return java.util.TimeZone.getDefault();
    }

    /**
    * A special type of JSF DataModel to allow a datatable and datapaginator
    * to page through a large set of data without having to hold the entire
    * set of data in memory at once.
    * Any time a managed bean wants to avoid holding an entire dataset,
    * the managed bean declares this inner class which extends PagedListDataModel
    * and implements the fetchData method. fetchData is called
    * as needed when the table requires data that isn't available in the
    * current data page held by this object.
    * This requires the managed bean (and in general the business
    * method that the managed bean uses) to provide the data wrapped in
    * a DataPage object that provides info on the full size of the dataset.
    */
    private class LocalDataModel extends PagedListDataModel {
        public LocalDataModel(int pageSize) {
            super(pageSize);
        }

        public DataPage<Usuarios> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPage(startRow, pageSize);
        }
    }

    private class LocalDataModelDTO extends PagedListDataModel {
        public LocalDataModelDTO(int pageSize) {
            super(pageSize);
        }

        public DataPage<UsuariosDTO> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPageDTO(startRow, pageSize);
        }
    }
}
